package com.acme.bankapp.service.app;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Analyzer {
	
	/**
	 * Outputs information about given class. The info is consists of fields,
	 * methods, annotations, modifiers, superclasses (up to Object) and interfaces.
	 * @param clazz Class to output information about.
	 */
	public static void analyze(Class<?> clazz) {
		System.out.println(String.format("Class '%1$s':\n", clazz.getCanonicalName()));
		Modifier.toString(clazz.getModifiers());
		Class<?> ancestor = clazz;
		do {
			System.out.print("<");
			System.out.print(ancestor.getName());
			ancestor = ancestor.getSuperclass();
		} while (ancestor != Object.class);
		System.out.println("\nInterfaces:\n");
		for (Class<?> iface : clazz.getInterfaces()) {
			System.out.print(" " + iface.getCanonicalName());
		}
		System.out.println("\nFields:\n");
		for (Field field : clazz.getFields()) {
			System.out.println(field.getType().getCanonicalName() + " " +
					field.getName());
		}
		System.out.println("\nMethods");
		for (Method method : clazz.getMethods()) {
			System.out.print(Modifier.toString(method.getModifiers()) + " " +
					method.getReturnType().getCanonicalName() + " " +
					method.getName());
			
			System.out.print(" throws ");
			Class<?>[] exceptions = method.getExceptionTypes();
			for (Class<?> exception : exceptions) {
				System.out.print(exception.getName() + " ");
			}

			System.out.print(" annotated ");
			Annotation[] annotations = method.getAnnotations();
			for (Annotation annotation : annotations) {
				System.out.print(annotation.annotationType().getName() + " ");
			}
			System.out.println();
		}
	}
}
